// 声明import.meta.env类型
declare global {
  interface ImportMeta {
    env: {
      VITE_MICRO_APP1_ENTRY?: string;
      VITE_MICRO_APP2_ENTRY?: string;
      VITE_MICRO_APP_BUILD_ENTRY?: string;
      VITE_MICRO_APP_DEVOPS_ENTRY?: string;
      VITE_MICRO_APP_VUE_DEVOPS_ENTRY?: string;
      [key: string]: any;
    };
  }
}

// CDN基础地址
const CDN_BASE = 'https://mybox-1257251314.cos.ap-chengdu.myqcloud.com/www/micro';

// CDN地址，作为环境变量不可用时的备选（生产版本）
const CDN_ENTRIES = {
  app1: `${CDN_BASE}/vue-app1/index.html`,
  app2: `${CDN_BASE}/vue-app2/index.html`,
  appBuild: `${CDN_BASE}/vue-build/index.html`,
  appDevops: `${CDN_BASE}/react-devops/index.html`,
  vueDevops: `${CDN_BASE}/vue-devops/index.html`
};

// 应用名称映射到 appId（用于灰度查询）
const APP_ID_MAP: Record<string, string> = {
  'app1': 'vue-app1',
  'app2': 'vue-app2',
  'app-build': 'vue-build',
  'react-devops': 'react-devops',
  'vue-devops': 'vue-devops'
};

import { grayReleaseApi } from './api/grayRelease';

/**
 * 批量查询用户的所有应用灰度版本（一次性查询，提高性能）
 * 开发和生产环境都查询，用于获取灰度状态
 * @param userId 用户ID
 * @returns 应用ID到版本号的映射，失败返回空对象
 */
async function getUserAllGrayVersions(userId: string): Promise<Record<string, string | null>> {
  if (!userId) {
    return {};
  }

  try {
    const res = await grayReleaseApi.getUserAllGrayVersions(userId);
    if (res && res.code === 200) {
      return res.data?.versions || {};
    }
    
    return {};
  } catch (error) {
    console.warn(`[批量灰度查询失败] userId=${userId}:`, error);
    return {};
  }
}

/**
 * 构建灰度版本的CDN路径
 * @param appId 应用ID
 * @param version 版本号
 * @returns CDN路径
 */
function buildGrayEntry(appId: string, version: string): string {
  return `${CDN_BASE}/${appId}/${version}/index.html`;
}

/**
 * 获取用户ID（从全局TokenManager）
 */
function getUserId(): string | null {
  const tokenInfo = (window as any).__TOKEN_MANAGER__?.getTokenInfo?.();
  return tokenInfo?.payload?.userId || null;
}

/**
 * 获取所有应用的灰度版本映射（缓存结果，避免重复查询）
 */
let grayVersionCache: Record<string, string | null> | null = null;
let grayVersionCacheTime: number = 0;
const GRAY_VERSION_CACHE_TTL = 5000; // 缓存5秒

/**
 * 尝试获取灰度版本入口地址
 * @param appName 应用名称
 * @param allGrayVersions 所有应用的灰度版本映射（可选，如果已查询则直接使用）
 */
async function tryGetGrayEntry(
  appName: string,
  allGrayVersions?: Record<string, string | null>
): Promise<string | null> {
  const userId = getUserId();
  if (!userId) {
    return null;
  }

  const appId = APP_ID_MAP[appName];
  if (!appId) {
    return null;
  }

  // 使用传入的版本映射，或从缓存获取
  let versions = allGrayVersions;
  if (!versions) {
    const now = Date.now();
    if (grayVersionCache && (now - grayVersionCacheTime) < GRAY_VERSION_CACHE_TTL) {
      versions = grayVersionCache;
    } else {
      versions = await getUserAllGrayVersions(userId);
      grayVersionCache = versions;
      grayVersionCacheTime = now;
    }
  }

  const grayVersion = versions[appId];
  if (!grayVersion) {
    return null;
  }

  return buildGrayEntry(appId, grayVersion);
}

/**
 * 格式化开发环境URL
 */
function formatDevUrl(devUrl: string): string {
  let url = devUrl;
  if (url.startsWith('//')) {
    url = window.location.protocol + url;
  }
  if (!url.endsWith('/index.html') && !url.endsWith('.html')) {
    url = url.endsWith('/') ? url + 'index.html' : url + '/index.html';
  }
  return url;
}

/**
 * 获取入口地址，优先使用环境变量，环境变量不存在时使用备选CDN地址
 * 支持灰度版本自动查询（开发环境查询状态但不使用，生产环境使用灰度版本）
 * @param envKey 环境变量键
 * @param cdnKey CDN键
 * @param devUrl 开发环境URL
 * @param appName 应用名称
 * @param allGrayVersions 所有应用的灰度版本映射（可选，用于批量查询优化）
 */
async function getEntry(
  envKey: string, 
  cdnKey: keyof typeof CDN_ENTRIES, 
  devUrl: string,
  appName: string,
  allGrayVersions?: Record<string, string | null>
): Promise<string> {
  // 优先使用环境变量
  const envValue = import.meta.env[envKey];
  if (envValue) {
    return envValue;
  }

  // 开发环境：查询灰度状态但不使用，直接使用本地地址
  if (!import.meta.env.PROD) {
    // 查询灰度状态（用于日志/调试，但不影响入口地址）
    const appId = APP_ID_MAP[appName];
    if (allGrayVersions && appId && allGrayVersions[appId]) {
      console.log(`[开发环境] ${appName} 存在灰度版本: ${allGrayVersions[appId]}, 但使用本地地址: ${formatDevUrl(devUrl)}`);
    }
    return formatDevUrl(devUrl);
  }

  // 生产环境：先尝试灰度版本，失败则使用生产CDN地址
  const grayEntry = await tryGetGrayEntry(appName, allGrayVersions);
  if (grayEntry) {
    return grayEntry;
  }

  return CDN_ENTRIES[cdnKey];
}

// 微应用配置接口
export interface MicroAppConfig {
  name: string;
  title: string;
  entry: string;
  activeRule: string;
  icon: string;
  sandbox?: any;
  sidebar: boolean;
  permission?: string;
  requiredRoles?: string[];
  container?: string;
  loader?: (loading: boolean) => void;
}

// 注意：由于 getEntry 现在是异步函数，我们需要在运行时动态设置 entry
// 这里先设置为占位符，实际会在应用初始化时更新
export const microApps: MicroAppConfig[] = [
  {
    name: 'app1',
    title: '全域管理',
    entry: '', // 将在运行时动态设置
    activeRule: '/app1',
    sandbox: {
      strictStyleIsolation: true, // 开启严格的样式隔离
      experimentalStyleIsolation: false, // 关闭实验性的样式隔离，使用严格隔离
    },
    icon: 'Document',
    sidebar: true,
    permission: 'app1:access',
    requiredRoles: ['SUPER_ADMIN','ADMIN', 'USER', 'TEACHER']
  },
  {
    name: 'app2',
    title: '应用二',
    entry: '', // 将在运行时动态设置
    activeRule: '/app2',
    sandbox: {
      strictStyleIsolation: true, // 开启严格的样式隔离
      experimentalStyleIsolation: false, // 关闭实验性的样式隔离，使用严格隔离
    },
    icon: 'Document',
    sidebar: true,
    permission: 'app2:access',
    requiredRoles: [] // 临时移除角色限制
  },
  {
    name: 'app-build',
    title: '构建中心',
    entry: '', // 将在运行时动态设置
    activeRule: '/app-build',
    sandbox: {
      strictStyleIsolation: true, // 开启严格的样式隔离
      experimentalStyleIsolation: false, // 关闭实验性的样式隔离，使用严格隔离
    },
    icon: 'DataBoard',
    sidebar: true,
    permission: 'build:access',
    requiredRoles: ['SUPER_ADMIN','ADMIN']
  },
  {
    name: 'react-devops',
    title: 'DevOps BI',
    entry: '', // 将在运行时动态设置
    activeRule: '/react-devops',
    sandbox: {
      strictStyleIsolation: true, // 开启严格的样式隔离
      experimentalStyleIsolation: false, // 关闭实验性的样式隔离，使用严格隔离
    },
    icon: 'Monitor',
    sidebar: false, // 隐藏 react-devops，改用 vue-devops
    permission: 'devops:access',
    requiredRoles: ['SUPER_ADMIN','ADMIN'],
    container: '#subapp-viewport',
    loader: (loading: boolean) => {
      // 加载状态处理
    }
  },
  {
    name: 'vue-devops',
    title: '埋点中心',
    entry: '', // 将在运行时动态设置
    activeRule: '/vue-devops',
    sandbox: {
      strictStyleIsolation: true, // 开启严格的样式隔离
      experimentalStyleIsolation: false, // 关闭实验性的样式隔离，使用严格隔离
    },
    icon: 'DataAnalysis',
    sidebar: true,
    permission: 'vue-devops:access',
    requiredRoles: ['SUPER_ADMIN','ADMIN']
  }
];

/**
 * 初始化微应用入口地址（支持灰度版本）
 * 优化：一次性查询所有应用的灰度版本，减少请求次数
 * 开发和生产环境都查询灰度状态，但开发环境使用本地地址，生产环境使用灰度CDN地址
 * 需要在应用启动时调用
 */
export async function initMicroAppEntries() {
  const entryConfigs = [
    { app: microApps[0], envKey: 'VITE_MICRO_APP1_ENTRY', cdnKey: 'app1', devUrl: '//localhost:9001', appName: 'app1' },
    { app: microApps[1], envKey: 'VITE_MICRO_APP2_ENTRY', cdnKey: 'app2', devUrl: '//localhost:9002', appName: 'app2' },
    { app: microApps[2], envKey: 'VITE_MICRO_APP_BUILD_ENTRY', cdnKey: 'appBuild', devUrl: '//localhost:9003', appName: 'app-build' },
    { app: microApps[3], envKey: 'VITE_MICRO_APP_DEVOPS_ENTRY', cdnKey: 'appDevops', devUrl: '//localhost:9004', appName: 'react-devops' },
    { app: microApps[4], envKey: 'VITE_MICRO_APP_VUE_DEVOPS_ENTRY', cdnKey: 'vueDevops', devUrl: '//localhost:9005', appName: 'vue-devops' },
  ];

  // 开发和生产环境都查询灰度版本状态（如果用户已登录）
  let allGrayVersions: Record<string, string | null> | undefined = undefined;
  
  const userId = getUserId();
  if (userId) {
    try {
      allGrayVersions = await getUserAllGrayVersions(userId);
      // 开发环境：记录灰度状态
      if (!import.meta.env.PROD && allGrayVersions) {
        const grayApps = Object.entries(allGrayVersions)
          .filter(([_, version]) => version !== null)
          .map(([appId, version]) => `${appId}:${version}`)
          .join(', ');
        if (grayApps) {
          console.log(`[开发环境] 当前用户存在灰度版本: ${grayApps}`);
        }
      }
    } catch (error) {
      console.warn('[批量查询灰度版本失败]:', error);
      // 如果批量查询失败，后续会降级到生产版本或本地地址
    }
  }

  // 并行初始化所有应用的入口地址
  await Promise.all(entryConfigs.map(async ({ app, envKey, cdnKey, devUrl, appName }) => {
    try {
      app.entry = await getEntry(envKey, cdnKey as keyof typeof CDN_ENTRIES, devUrl, appName, allGrayVersions);
    } catch (error) {
      // 失败时使用生产版本或本地地址
      console.error(`[初始化入口地址失败] ${appName}:`, error);
      if (import.meta.env.PROD) {
        app.entry = CDN_ENTRIES[cdnKey as keyof typeof CDN_ENTRIES];
      } else {
        app.entry = formatDevUrl(devUrl);
      }
    }
  }));
}

// 导出辅助函数和常量
export { getUserAllGrayVersions, buildGrayEntry, CDN_BASE, APP_ID_MAP }; 